<?php

/**
 * Created by Sven.
 * Date: 2016/12/16
 * Time: 10:48
 * 模板解析类
 */
class Parser {
    private $_tpl = '';

    public function __construct( $_tplFile = '' ) {
        // 读取模板文件内容
        if ( !$this->_tpl = file_get_contents( $_tplFile ) ) {
            exit( 'ERROR: 获取模板文件内容失败' );
        }
    }

    // 解析普通变量
    private function parVar() {
//        $_pattern = '/\{\$([\w]+(\-\>[\w])*)\}/';
        $_pattern = '/\{\$([\w]+)(\-\>([\w]+))*\}/'; // 支持 {$value}  {$obj->value}
        if ( preg_match( $_pattern, $this->_tpl, $_matchs ) ) {
            $this->_tpl = preg_replace( $_pattern, '<?php echo isset($this->_vars["$1"]$2) ? $this->_vars["$1"]$2 : "" ?>', $this->_tpl );
        }
    }

    // 解析if语句
    private function parIf() {
        $_patternIf = '/\{if\s+\$([\w]+)\}/';
        $_patternEndIf = '/\{\/if\}/';
        $_patternElse = '/\{else\}/';

        if ( preg_match( $_patternIf, $this->_tpl ) ) {
            if ( preg_match( $_patternEndIf, $this->_tpl ) ) {
                $this->_tpl = preg_replace( $_patternIf, '<?php if( isset( $this->_vars["$1"] ) && !empty( $this->_vars["$1"] )  ) { ?>', $this->_tpl );
                $this->_tpl = preg_replace( $_patternEndIf, '<?php } ?>', $this->_tpl );

                if ( preg_match( $_patternElse, $this->_tpl ) ) {
                    $this->_tpl = preg_replace( $_patternElse, '<?php } else { ?>', $this->_tpl );
                }

            } else {
                exit( 'ERROR： IF语句没有关闭！ ' );
            }
        }
    }


    // 解析注释
    private function parComment() {
        $_patternComment = '/\{\*/';
        $_patternEndComment = '/\*\}/';

        if ( preg_match( $_patternComment, $this->_tpl ) ) {
            if ( preg_match( $_patternComment, $this->_tpl ) ) {
                $this->_tpl = preg_replace( $_patternComment, '<?php /* ?>', $this->_tpl );
                $this->_tpl = preg_replace( $_patternEndComment, '<?php */ ?>', $this->_tpl );

            } else {
                exit( 'ERROR: 注释没有关闭' );
            }
        }
    }

    // 解析include
    private function parInclude() {
//        $_patternInclude = '/{include\s+file=[\'\"]([\w-\.]+)[\'\"]}/';
        $_patternInclude = '/{include\s+file=([\"\'])([\w-\.\/]+)\1\}/';// 支持斜杠、支持单双引号
        if ( preg_match_all( $_patternInclude, $this->_tpl, $matchs ) ) {
            foreach ($matchs[2] as $_file){
                if ( empty( $_file )  || !file_exists( ROOT_PATH . '/templates/' .$_file ) ) {
                    exit( 'ERROR: 文件'.$_file.'错误或者文件不存在' );
                }

            }

            $this->_tpl = preg_replace( $_patternInclude, '<?php global $_tpl; $_tpl->create("$2"); ?>', $this->_tpl );
        }
    }

    // 解析foreach
    private function parForeach() {
        $_patternForeach = '/\{foreach\s+\$([\w]+)\(([\w]+),([\w]+)\)\}/';
        $_patternEndForeach = '/\{\/foreach\}/';
//        $_patternVar = '/\{@([\w]+)\}/';
        $_patternVar = '/\{@([\w\+]+(\-\>[\w]+)*)\}/';  // 支持 {@value} 和 {@value->id} 的键值对形式
        if ( preg_match( $_patternForeach, $this->_tpl ) ) {
            if ( preg_match( $_patternForeach, $this->_tpl ) ) {
                $this->_tpl = preg_replace( $_patternForeach, '<?php if (isset($this->_vars["$1"]) ) { foreach($this->_vars["$1"] as $$2 => $$3) { ?>', $this->_tpl );
                $this->_tpl = preg_replace( $_patternEndForeach, '<?php }  }?>', $this->_tpl );

                // 替换循环变量
                if ( preg_match( $_patternVar, $this->_tpl ) ) {
                    $this->_tpl = preg_replace( $_patternVar, '<?php echo $$1; ?>', $this->_tpl );
                }

            } else {
                exit( 'ERROR: 没有关闭foreach语句' );
            }
        }
    }

    private function parConst(){
        $_pattern = '/\{\#([\w]+)\}/'; //  {$CONFIG}
        if ( preg_match( $_pattern, $this->_tpl, $_matchs ) ) {
            $this->_tpl = preg_replace( $_pattern, '<?php   echo defined("$1") ?  $1 : "" ; ?>', $this->_tpl );
        }

    }

    private function parSuperGlobalVar(){
        $_pattern = '/\{([\w]+)\(([\w]+)\)\}/';
        if ( preg_match( $_pattern, $this->_tpl ) ) {
            $this->_tpl = preg_replace( $_pattern, '<?php echo  $_$1["$2"]; ?>', $this->_tpl );
        }
    }

    // 解析系统变量
    private function configVar() {
        // <!--{name}-->
        $_patternVar = '/<!--{([\w]+)}-->/';
        if ( preg_match( $_patternVar, $this->_tpl ) ) {
            $this->_tpl = preg_replace( $_patternVar, '<?php echo $this->_configs["$1"]; ?>', $this->_tpl );
        }
    }

    // 生成编译文件
    public function compile( $_parFile = '' ) {
        // 解析模板内容
        $this->parVar();
        $this->parIf();
        $this->parComment();
        $this->parInclude();
        $this->parForeach();
        $this->parConst();
        $this->parSuperGlobalVar();
        $this->configVar();

        // 写入编译文件
        if ( !file_put_contents( $_parFile, $this->_tpl ) ) {
            exit( 'ERROR: 写入编译文件内容失败' );
        }
    }


}